#ifndef _OPENCL_INTERSECT_DEVICE_H_
#define _OPENCL_INTERSECT_DEVICE_H_

#include <vector>
#include <queue>
#include <memory>

#include "ray.h"
#include "primitive.h"
#include "scene_data.h"

struct IntersectDevicePrivateData;
class OpenCLIntersectDevice{
public:
	enum PopMode{PopModeEnqueue,PopModeForceWait };
	OpenCLIntersectDevice(const scene_info_memory_t& scene_info_memory,const size_t ray_buffer_size,const size_t max_queue_size);
	std::shared_ptr<std::vector<ray_t> > CreateRayBuffer(const size_t ray_buffer_size);
	void PushRayBuffer(const std::shared_ptr<std::vector<ray_t> > ray_buffer);
	bool PopIntersectionBuffer( std::shared_ptr<std::vector<ray_t> >* ray_buffer, std::vector<intersection_t>* isects);

	~OpenCLIntersectDevice();
public:
	static void InitializeKernel(const scene_info_memory_t& scene_info);
private:
	OpenCLIntersectDevice(const OpenCLIntersectDevice&);
	OpenCLIntersectDevice& operator=(const OpenCLIntersectDevice&);
private:
	size_t ray_buffer_size_;
	std::queue<std::shared_ptr<std::vector<ray_t> > > ray_buffer_queue_;
	std::queue<std::vector<intersection_t> > intersection_buffer_queue_;
	PopMode pop_mode_;//detect if force pop to empty the queue
	const size_t max_queue_size_;

	IntersectDevicePrivateData* private_data_;

	const scene_info_memory_t& scene_info_memory_;
};

#endif